////1、实现strlen函数
//#include<stdio.h>
//#include<assert.h>
//int strlen(const char* arr){//修饰,因为不改变arr的值
//    assert(arr!=NULL);
//    int count=0;
//    //注意这里的\0要用单引号，表示一个字符
//    while(*arr!='\0'){//因为这里的0代表的是ascii值为0，也就是NULL和'\0'，而字符串里的是字符0，字符0ASCII值为48，所以不算（当里面填0的时候
//        arr++;//让地址++，不用加*
//        count++;
//    }
//    return count;
//}
//int main(){
//    char arr[]="zhangyang";
//    printf("%d",strlen(arr));
//    return 0;
//}



////2.1strcpy实现
//#include<stdio.h>
//#include <assert.h>
//
//char* cpy(char*arr,const char*arr1){
//    assert(arr!=NULL&&arr1!=NULL);
//    char *ret=arr;
//    while ((*arr++=*arr1++)!='\0');//
//        return ret;
//}
//
//int main(){
//    char arr[]="zhang";
//    char arr1[]="yang";
//    printf("%s",cpy(arr,arr1));
//    return 0;
//}


////2.2strcpy的实现(自写待测//错的
//#include<stdio.h>
//#include <assert.h>
//void mystrcpy(char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    while(*arr1++=*arr2++){};
//}
//int main(){
//    char arr1[]={"abcdef"};
//    char arr2[]={"zhang"};
//    mystrcpy(arr1,arr2);
//    printf("%s",arr1);
//    return 0;
//}



////2.3视频解法://和上面自己写的差不多
//#include<stdio.h>
//#include <assert.h>
//
//char* mystrcpy(char*arr1,const char*arr2){
//    assert(arr1!=NULL&&arr2!=NULL);  //也可以assert(arr1&&arr2)
//    char*ret=arr1;
//    while(*arr1++=*arr2++){}
//    return ret;
//}
//int main(){
//    char arr1[]={"abcdef"};
//    char arr2[]={"zhang"};
//    printf("%s",mystrcpy(arr1,arr2));
//    return 0;
//}



////2.4strncpy(多出来个选择复制几个字符的功能:
//#include<stdio.h>
//#include <assert.h>
//char* strncpyy(char*arr1,const char*arr2,int k){
//    assert(arr1);
//    assert(arr2);
//    char*ret=arr1;
//    while(k&&(*arr1++=*arr2++)!='\0'){
//        k--;
//    }
//    *arr1='\0';
//    return ret;
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"younger"};
//    printf("%s",strncpyy(arr1,arr2,4));
//    return 0;
//}





////3.1strcat函数实现(自己实现的方法
//#include<stdio.h>
//#include <assert.h>
//void mystrcat(char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    while(*arr1!='\0'){
//        arr1++;
//    }
//    while(*arr1=='\0'){
//        *arr1=*arr2;
////        arr2+=1;     不要加这条
//    }
//    while(*arr1!='\0'){
//        *arr1++=*arr2++;
//    }
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"yang"};
//    mystrcat(arr1,arr2);
//    printf("%s",arr1);
//    return 0;
//}


////3.2strcat函数实现(视频
//#include<stdio.h>
//#include <assert.h>
//char* strcatt(char*arr1,const char*arr2){ //没加const，减分
//    assert(arr1);
//    assert(arr2);
//    char* ret=arr1;
//    while(*arr1!='\0'){
//        arr1++;
//    }
//    while(*arr1++=*arr2++){;}
//    return ret;
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"yang"};
//    printf("%s",strcatt(arr1,arr2));
//    return 0;
//}


////3.3strncat实现:
//#include<stdio.h>
//#include <assert.h>
//char* strncatt(char*arr1,const char*arr2,int n){
//    assert(arr1);
//    assert(arr2);
//    char*ret=arr1;//指向要返回的地址
//    while(*arr1!='\0'){//把arr1加到'\0'这个位置
//        arr1++;
//    }
//    while(n&&(*arr1++=*arr2++)!='\0'){//完成赋值，直到两个字符数组元素都为0时或者n为0时结束
//        n--;
//    }
//    *arr1='\0';//因为上一步在arr2等于'\0'时就停止了，还没有给arr1赋值'\0'
//    return ret;//指针存的地址
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"zhang"};
//    printf("%s",strncatt(arr1,arr2,6));
//    return 0;
//}




////4.1strcmp的实现
//#include<stdio.h>
//#include <assert.h>
//int strcmpp(const char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    while(*arr1==*arr2){//这是比较不是赋值，也就是说当双方都是\0的时候为真，也就是1,并且这里不能用*arr1++==*arr2++,
//                    因为这个是每次用的时候++,会导致arr地址多+一次,所以可能你上面遇到不相同的字母时也++了，就相当于跳过了那两个不同的字母
//        if(*arr1=='\0'){
//            return 0;
//        }
//        arr1++;
//        arr2++;
//    };
//    if(*arr1>*arr2){//要注意直接拿arr的话，比较的不是【字符】的大小,比较的是首元素的地址
//        return 1;
//    }
//    else{
//        return -1;
//    }
//}
//int main(){
//    char arr1[]={"zahang"};
//    char arr2[]={"zbhang"};
//    int ret=strcmpp(arr1,arr2);
//    printf("%d",ret);
//    return 0;
//}



////4.2strcmp的实现(返回数值不同版
//#include<stdio.h>
//#include <assert.h>
//int strcmpp(const char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    while(*arr1==*arr2){
//        if(*arr1=='\0'){
//            return 0;
//        }
//        arr1++;
//        arr2++;
//    }
//    return (*arr1-*arr2);
//}
//int main(){
//    char arr1[]={"ahang"};
//    char arr2[]={"zng"};
//    int ret=strcmpp(arr1,arr2);
//    printf("%d",ret);
//    return 0;
//}



////4.3strcmp更简单版本
#include<stdio.h>
#include <assert.h>
//int strcmpp(const char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    while(*arr1&&*arr2&&*arr1==*arr2){
//        arr1++;
//        arr2++;
//    }
//    return *arr1-*arr2;
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"zhanz"};
//    printf("%d",strcmpp(arr1,arr2));
//    return 0;
//}




////4.4strncmp（自写:
//#include<stdio.h>
//#include <assert.h>
//int strncmpp(const char*arr1,const char*arr2,int k){
//    assert(arr1);
//    assert(arr2);
//    while(k&&*arr1==*arr2){
//        k--;//注意这里别忘了设置好循环终止条件,也可以在while里写--k
//        if(k==0||*arr1=='\0'){
//            return 0;
//        }
//        arr1++;
//        arr2++;
//    }
//    return *arr1-*arr2;
//
//}
//int main(){
//    const char arr1[]={"zhang"};
//    const char arr2[]={"zhanz"};
//    printf("%d",strncmpp(arr1,arr2,5));
//    return 0;
//}





////4.5strncmp for循环做法:
//#include<stdio.h>
//#include <assert.h>
//int strncmpp(char*arr1,char*arr2,int k){
//    assert(arr1);
//    assert(arr2);
//    int i=0;
//    for(i=0;i<k;i++){
//        if(*(arr1+i)>*(arr2+i)){
//            return 1;
//        }
//        else if (*(arr1+i)<*(arr2+i)){
//            return -1;
//        }
//        else if(*(arr1+i)==0||*(arr2+i)==0){
//            break;//注意这里是break不是return0，当不是大于也不是小于的情况下，直接会到下一个i，不判断*arr1==*arr2，
//            // 直到其中一个字符数组到'\0'时跳出循环，说明前面的都相等了，循环外面return 0就派上用场了
//        }
//    }
//    return 0;
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"zhanz"};
//    printf("%d",strncmpp(arr1,arr2,4));
//    return 0;
//}




////4.6strncmp 最简单的写法？
//#include<stdio.h>
//#include <assert.h>
//int strncmpp(const char*arr1,const char*arr2,int k){
//    assert(arr1);
//    assert(arr2);
//    while(k--){
//        if(*arr1==0||*arr1!=*arr2){
//            return *arr1-*arr2;
//        }
//        arr1++;//给if创建循环条件
//        arr2++;
//    }
//}
//int main(){
//    char arr1[]={"zhang"};
//    char arr2[]={"zhanz"};
//    printf("%d",strncmpp(arr1,arr2,5));
//    return 0;
//}






////5.1strstr实现:
//#include<stdio.h>
//#include <assert.h>
//char* strstrr(const char*arr1,const char*arr2){
//    assert(arr1);
//    assert(arr2);
//    char* s1,*s2;
//    char* cur=(char*)arr1;//arr1是const char*，是受保护的，要使用char*接收的话需要强制类型转换
//    if(*arr2=='\0'){
//        return (char*)arr1;
//    }
//    while(*cur){
//        s1=cur;
//        s2=(char*)arr2;//这两步不能少,s1设定调整每次比对的母串起始位置，s2设定子串起始位置
//        while(*s1&&*s2&&(*s1==*s2)){//循环中设定了要用的变量就不能再使用外部变量进行操作
//            s1++;
//            s2++;
//        }
//        if(*s2=='\0'){//也可以写成(!*s2),!的意思就是否,!0为真，!1为假
//            return cur;
//        }
//        cur++;//是++不是--，因为只有++才能让cur往后走，直到'\0'
//    }
//    return NULL;
//}
//int main(){
//    char arr1[]={"zhanggzhang"};
//    char arr2[]={"zhanggzhang"};
//    printf("%s",strstrr(arr1,arr2));
//    return 0;
//}



////6.1memcpy(有问题的版本):
//#include<stdio.h>
//#include<assert.h>
//struct s{
//    char name[20];
//    int age;
//};
//void* memcpyy(void*stu2,const void*stu1,size_t k){
//    assert(stu1);
//    assert(stu2);
//    void*ret=stu2;//要返回的值需要是原来的格式
//    while(k--){
//        *(char*)stu2=*(char*)stu1;
//        (char*)stu1++;//视频里是前置++，这样的话++作用于整个表达式，而整个表达式是
//                      一个右值(强制类型转换后产生的新值，是具体的值，值不变，值的类型变了，stu1本身还是void*），右值不能被赋值
//        (char*)stu2++;
//    }
//    return ret;
//}
//int main(){
//    struct s stu1[]={{"younger",18},{"yang",21}};//结构体里面的元素是用{}来括起来的
//    struct s stu2[3]={0};
//    char*ret=memcpyy(stu2,stu1,sizeof(stu1));
//    printf("%s",ret);
//    return 0;
//}




////6.2memcpyy(没问题的版本):
//#include<stdio.h>
//#include<assert.h>
//struct s{
//    char name[20];
//    int age;
//};
//void* memcpyy(void*stu2,const void*stu1,size_t k){
//    assert(stu1);
//    assert(stu2);
//    void* ret=stu2;
//    char*ret1=(char*)stu2;
//    char*ret2=(char*)stu1;
//    while(k--){
//        *ret1++=*ret2++;
//    }
//    return ret;
//}
//int main(){
//    struct s stu1[]={{"zhang",18},{"yang",21}};
//    struct s stu2[3]={0};
//    char* ret=memcpyy(stu2,stu1,sizeof(stu1));
//    printf("%s",ret);
//    return 0;
//}






////7.memmove正确写法:
#include<stdio.h>
#include<assert.h>
//void* memmovee(const void*src,void*dest,size_t k){
//    assert(src);
//    assert(dest);
//    void*ret=dest;
//    char*srcc=(char*)src;
//    char*destt=(char*)dest;
//    if(srcc<destt&&srcc+k>destt){
//        while(k--){
//            *(destt+k)=*(srcc+k);
//            destt--;
//            srcc--;
//        }
//    }
//    else{
//        while(k--){
//            *destt=*srcc;
//            destt++;
//            srcc++;
//        }
//    }
//    return ret;
//}
//int main(){                       //可以改成字符之类的
//    int arr[]={1,2,3,4,5,6,7,8,9};
//    memmovee(arr,arr+2,8);
//    int i=0;
//    for(i=0;i<9;i++){
//        printf("%d ",arr[i]);
//    }
//    return 0;
//}